<html>
<head><meta charset="utf-8"><title>updating uninitialized swapping · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html">updating uninitialized swapping</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="188944396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188944396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188944396">(Feb 24 2020 at 16:58)</a>:</h4>
<p>Does this seem like the correct replacement / upgrade guide?</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">switch</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// This is safe since we will overwrite it without ever reading it.</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mem</span>::<span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">mem</span>::<span class="n">uninitialized</span><span class="p">()</span><span class="w"> </span><span class="p">});</span><span class="w"></span>
<span class="w">    </span><span class="c1">// We absolutely must **never** panic while the uninitialized value is around!</span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">Foo</span>::<span class="n">Bar</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">Baz</span><span class="p">(</span><span class="n">val</span><span class="p">),</span><span class="w"></span>
<span class="w">        </span><span class="n">Foo</span>::<span class="n">Baz</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">Bar</span><span class="p">(</span><span class="n">val</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">uninitialized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mem</span>::<span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">new</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">uninitialized</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>New</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">switch</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">this</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">MaybeUninit</span><span class="o">&lt;</span><span class="n">Self</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mem</span>::<span class="n">transmute</span><span class="p">(</span><span class="bp">self</span><span class="p">);</span><span class="w"></span>

<span class="w">        </span><span class="c1">// After this line, `self` and `this` are effectively undefined and</span>
<span class="w">        </span><span class="c1">// must not be read until we re-establish a value. This also means</span>
<span class="w">        </span><span class="c1">// that the code must **not** panic!</span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">read</span><span class="p">(</span><span class="n">this</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">());</span><span class="w"></span>

<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">Foo</span>::<span class="n">Bar</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">Baz</span><span class="p">(</span><span class="n">val</span><span class="p">),</span><span class="w"></span>
<span class="w">            </span><span class="n">Foo</span>::<span class="n">Baz</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">Bar</span><span class="p">(</span><span class="n">val</span><span class="p">),</span><span class="w"></span>
<span class="w">        </span><span class="p">};</span><span class="w"></span>

<span class="w">        </span><span class="n">ptr</span>::<span class="n">write</span><span class="p">(</span><span class="n">this</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">new</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="188945571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188945571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188945571">(Feb 24 2020 at 17:11)</a>:</h4>
<p>The <code>read</code> and <code>write</code> seem reasonable, but that <code>transmute</code> feels heavy-handed.</p>



<a name="188946729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188946729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188946729">(Feb 24 2020 at 17:25)</a>:</h4>
<p>You can go through raw pointer casts if you want - <code>&amp;mut *(self as *mut Self as *mut MaybeUninit&lt;Self&gt;)</code></p>



<a name="188946774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188946774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188946774">(Feb 24 2020 at 17:25)</a>:</h4>
<p>might also be worth adding an abort-on-unwind guard type as a bit of extra insurance</p>



<a name="188946827"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188946827" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188946827">(Feb 24 2020 at 17:26)</a>:</h4>
<p>a transmute seems preferable and less of a footgun, cc <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="188947059"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188947059" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188947059">(Feb 24 2020 at 17:28)</a>:</h4>
<p>This is <a href="https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html" target="_blank" title="https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html">https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html</a>  tho so I wouldn't roll my own inline version of that</p>



<a name="188948311"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188948311" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188948311">(Feb 24 2020 at 17:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116155">Jake Goulding</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/188945571" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/188945571">said</a>:</p>
<blockquote>
<p>The <code>read</code> and <code>write</code> seem reasonable, but that <code>transmute</code> feels heavy-handed.</p>
</blockquote>
<p><code>uninitialized</code> is in some sense a much bigger hammer than <code>transmute</code> though, I'd say</p>



<a name="188952652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188952652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188952652">(Feb 24 2020 at 18:34)</a>:</h4>
<p>The <code>take_mut</code> crate doesn't use <code>MaybeUninit</code>; does that worry anyone?</p>



<a name="188953370"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188953370" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188953370">(Feb 24 2020 at 18:43)</a>:</h4>
<p>It should be fine, it never uses undefined bytes.</p>



<a name="188961578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188961578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188961578">(Feb 24 2020 at 20:14)</a>:</h4>
<blockquote>
<p>it never uses undefined bytes.</p>
</blockquote>
<p>I'm not sure I follow. Seems like if I take that argument to the end, there was never a need for <code>MaybeUninit</code> in the first place, so long as people never used undefined bytes.</p>



<a name="188999870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188999870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188999870">(Feb 25 2020 at 08:27)</a>:</h4>
<p>The comment is definitely incorrect</p>



<a name="188999970"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/188999970" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#188999970">(Feb 25 2020 at 08:29)</a>:</h4>
<p>the panic danger is not that self and this are both uninitialized. The panic danger is that tmp is a byte duplicate of a non-Copy type so you're in danger of a double drop.</p>



<a name="189000174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189000174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189000174">(Feb 25 2020 at 08:33)</a>:</h4>
<p>In fact, because of the way read and write are used in the new version, there's absolutely no need for uninit at all.</p>



<a name="189004154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189004154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189004154">(Feb 25 2020 at 09:43)</a>:</h4>
<p>I agree with <span class="user-mention" data-user-id="224471">@Lokathor</span> There's no need in your code for MaybeUninit. there's only a need to prevent panicking and dropping. because if it has a non trivial Drop impl it can then use after free or read uninit bytes etc.</p>



<a name="189100374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189100374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189100374">(Feb 26 2020 at 10:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116155">Jake Goulding</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/188961578" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/188961578">said</a>:</p>
<blockquote>
<blockquote>
<p>it never uses undefined bytes.</p>
</blockquote>
<p>I'm not sure I follow. Seems like if I take that argument to the end, there was never a need for <code>MaybeUninit</code> in the first place, so long as people never used undefined bytes.</p>
</blockquote>
<p>ah, and again we have confusion about the word "use"</p>



<a name="189100429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189100429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189100429">(Feb 26 2020 at 10:07)</a>:</h4>
<p>the term we use in the reference now is "you must not <em>produce</em> an invalid value".<br>
<code>MaybeUninit::&lt;bool&gt;::uninit().assume_init()</code> produces a <code>bool</code> that is invalid, hence it is UB.<br>
<code>take_mut</code>, however, never does anything like that.</p>



<a name="189100503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189100503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189100503">(Feb 26 2020 at 10:08)</a>:</h4>
<p>doing <code>ptr::read</code> on an <code>&amp;mut T</code> does not <em>produce</em> an invalid value anywhere -- the only value it produces at all is what gets returned, which is a valid <code>T</code> (assuming there wasn't already something wrong with the reference)</p>



<a name="189163620"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189163620" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189163620">(Feb 26 2020 at 21:52)</a>:</h4>
<p>What happens if you read from <code>&amp;mut &amp;mut T</code>?  Can you end up with 2 unique pointers pointing to the same location?</p>



<a name="189165745"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189165745" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189165745">(Feb 26 2020 at 22:13)</a>:</h4>
<p>yes actually.</p>
<p><code>ptr::read</code> doesn't in any way affect what you read from, so there's no "de-initialization" or anything like that (despite what many people seem to believe).</p>



<a name="189169649"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189169649" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189169649">(Feb 26 2020 at 22:54)</a>:</h4>
<p>Does that mean that the <code>take_mut</code> crate is unsound? It does pretty much this.<br>
<a href="https://docs.rs/take_mut/0.2.2/src/take_mut/lib.rs.html#31-41" target="_blank" title="https://docs.rs/take_mut/0.2.2/src/take_mut/lib.rs.html#31-41">https://docs.rs/take_mut/0.2.2/src/take_mut/lib.rs.html#31-41</a><br>
And if it is unsound then is there a way to make it sound?</p>



<a name="189186122"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189186122" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189186122">(Feb 27 2020 at 04:28)</a>:</h4>
<p>So I got up from a nap, and happened to check Zullip first, and you really made my heart sink with this one. :(</p>
<p>You'd have to run Miri on it to be sure. Maybe I'm wrong and this particular code flow is somehow a freakish edgecase that is allowed. I don't think so though. I think it really is unsound if T is a unique reference (or something that contains a unique reference).</p>
<p>If there is a problem, I don't think there's any possible fix in the general case.</p>
<p>You could add a bound of <code>where T: 'static</code> to the function, but that can be evaded if you have <code>&amp;'static mut T</code>. That sounds silly for a moment maybe, until you remember that <code>Box::leak</code> is officially stable and safe and gives you <code>&amp;'a mut T</code> when you leak the box and it <em>goes out of its way</em> to say you can have 'a be 'static if your referenced type is 'static.</p>



<a name="189190892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189190892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189190892">(Feb 27 2020 at 06:45)</a>:</h4>
<p>take_mut uses catch_unwind, but that won't catch foreign exceptions.</p>



<a name="189194159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189194159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189194159">(Feb 27 2020 at 08:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189163620" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189163620">said</a>:</p>
<blockquote>
<p>What happens if you read from <code>&amp;mut &amp;mut T</code>?  Can you end up with 2 unique pointers pointing to the same location?</p>
</blockquote>
<p>this is where the details of the aliasing model really become relevant -- e.g., <a href="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md">Stacked Borrows</a>. A more concrete example would help me answer your question.</p>



<a name="189194181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189194181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189194181">(Feb 27 2020 at 08:17)</a>:</h4>
<p>but <code>take_mut</code> should be fine, I think -- the uniqueness is not about which references <em>exist</em> but about which <em>get used</em></p>



<a name="189194223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189194223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189194223">(Feb 27 2020 at 08:18)</a>:</h4>
<p>(where "use" is defined rather loosely, and a reborrow or assignment/move/copy is already a use)</p>



<a name="189194257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189194257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189194257">(Feb 27 2020 at 08:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189190892" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189190892">said</a>:</p>
<blockquote>
<p>take_mut uses catch_unwind, but that won't catch foreign exceptions.</p>
</blockquote>
<p>I dont think there are non-UB foreign exceptions in Rust as of today?</p>



<a name="189194767"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189194767" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189194767">(Feb 27 2020 at 08:30)</a>:</h4>
<p>Indeed, but there will be in the future.</p>



<a name="189196584"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189196584" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189196584">(Feb 27 2020 at 09:02)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> So... a person <em>can</em> have two unique references to the same location as long as they don't actually use both of them?</p>
<p>That seems quite different from the previous position of "any aliasing is immediately UB (even before you do anything with it)"</p>



<a name="189197391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197391">(Feb 27 2020 at 09:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189194767" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping/near/189194767">said</a>:</p>
<blockquote>
<p>Indeed, but there will be in the future.</p>
</blockquote>
<p>this seems pretty relevant for the unwinding discussion then -- adding kinds of uwninding that <code>catch_unwind</code> does not catch could make take_mut, rayon and other libraries unsound</p>



<a name="189197403"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197403" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197403">(Feb 27 2020 at 09:17)</a>:</h4>
<p>is that already on the radar of the FFI-unwind group? Where would be a good point to raise this?</p>



<a name="189197423"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197423" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197423">(Feb 27 2020 at 09:17)</a>:</h4>
<p>Cc <span class="user-mention" data-user-id="116009">@nikomatsakis</span> <span class="user-mention" data-user-id="120076">@BatmanAoD (Kyle Strand)</span></p>



<a name="189197504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197504">(Feb 27 2020 at 09:18)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> I mean, safe code can have two mutable references to the same location as long as it doesnt use both of them... </p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="c1">// x and y are aliasing</span>
</pre></div>



<a name="189197543"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197543" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197543">(Feb 27 2020 at 09:19)</a>:</h4>
<p>I dont think I ever said "any aliasing is UB", I said "just creating the reference counts as access and causes UB <em>if there is a conflict</em>"</p>



<a name="189197557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197557">(Feb 27 2020 at 09:19)</a>:</h4>
<p>but if all uses/reborrows/reference creations are well-nested following the stack, there's no conflict</p>



<a name="189197576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197576">(Feb 27 2020 at 09:19)</a>:</h4>
<p>but the take_mut case doesn't follow the stack really</p>



<a name="189197628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197628">(Feb 27 2020 at 09:20)</a>:</h4>
<p>you'd have like... two elements at the same stack depth, uh, sorta</p>



<a name="189197792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189197792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189197792">(Feb 27 2020 at 09:24)</a>:</h4>
<p>that's not really possible. I guess I need to see some concrete code to understand what you are concerned about.</p>



<a name="189206645"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189206645" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189206645">(Feb 27 2020 at 11:53)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> regarding unwinding the best place to ask is <a class="stream" data-stream-id="210922" href="/#narrow/stream/210922-project-ffi-unwind">#project-ffi-unwind</a></p>



<a name="189206676"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189206676" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189206676">(Feb 27 2020 at 11:53)</a>:</h4>
<p>But yes, <code>catch_unwind</code> can only catch Rust panics because it has to return a <code>Box&lt;Any&gt;</code>. This is not possible for foreign exceptions.</p>



<a name="189207066"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189207066" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189207066">(Feb 27 2020 at 12:01)</a>:</h4>
<p>I guess we could return a <code>Box&lt;ForeignException&gt;</code>, but then if you try to rethrow that with <code>resume_unwind</code> you get a Rust panic, not the original foreign exception.</p>



<a name="189228948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189228948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189228948">(Feb 27 2020 at 16:24)</a>:</h4>
<p>probably catch_foreign_exception as a separate utility would be best</p>



<a name="189279693"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189279693" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189279693">(Feb 28 2020 at 02:59)</a>:</h4>
<blockquote>
<p>probably catch_foreign_exception as a separate utility would be best</p>
</blockquote>
<p>I can't imagine any realistic case where you'd want to catch only foreign exceptions and not rust panics</p>



<a name="189288172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189288172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189288172">(Feb 28 2020 at 07:03)</a>:</h4>
<p>immediately around an ffi call of course</p>



<a name="189294407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189294407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189294407">(Feb 28 2020 at 09:20)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> you are right, sorry for the noise, I'll move the unwinding thing there</p>



<a name="189347963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189347963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thales Fragoso <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189347963">(Feb 28 2020 at 20:31)</a>:</h4>
<p>(deleted)</p>



<a name="189348050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating%20uninitialized%20swapping/near/189348050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thales Fragoso <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/updating.20uninitialized.20swapping.html#189348050">(Feb 28 2020 at 20:32)</a>:</h4>
<p>(deleted)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>